// TODO  Well-known symbols
//  除了自己创建的symbol，JavaScript还内建了一些在ECMAScript 5 之前没有暴露给开发者的symbol，它们代表了内部语言行为。它们可以使用以下属性访问：
//  https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Symbol

// 12个


//3. Symbol.iterator
//类数组转化成数组
function ajax(/*...args*/){
  //arguments是一个类数组
  // 类数组是一个长这样的对象->{0:'url',1:'get',length:2,[Symbol.iterator](){}}

  // console.log(Array.from(arguments));
  // console.log(Array.from({0:1,1:2,length:2})); //Array.from 转化类数组只需要有length就好

  // console.log([...arguments]);
  /*
    Array.from 是根据length 遍历每一项 将每一项变成数组成员

    而[...{}] 是通过迭代器来实现
  */
  console.log([...{
    0: 1, 1: 2, /*length: 2, */[Symbol.iterator] () {
      //this指向当前对象
      let self = this;
      const m = Object.keys(this).length
      let i = 0;
      return {
        next(){
          return {value:self[i],done:i++===m}
        }
      }
    }}]); //[1,2]

  //[Symbol.iterator] 是个函数，只要运行后返回一个对象他可以.next就行，SO也可以写成这样
  /*console.log([...{
    0: 1, 1: 2, /!*length: 2, *!/[Symbol.iterator]: function* () {
      //this指向当前对象
      const m = Object.keys(this).length
      let i = 0;
      while (m !== i){
        yield this[i++]; // {value:0,done:false}
      }
    }}]); //[1,2]*/
}
ajax('url', 'get');


//5. Symbol.species
//一个用于创建派生对象的构造器函数。
/*
知名的 Symbol.species 是个函数值属性，其被构造函数用以创建派生对象。
*/
/*
你可能想在扩展数组类 MyArray 上返回 Array 对象。
 例如，当使用例如 map() 这样的方法返回默认的构造函数时
 ，你希望这些方法能够返回父级的 Array 对象，以取代 MyArray 对象。
 Symbol.species 允许你这么做：
*/
class MyArray extends Array {
  // 覆盖 species 到父级的 Array 构造函数上
  static get [Symbol.species]() { return Array; }
}
var a = new MyArray(1,2,3);
var mapped = a.map(x => x * x);
console.log(mapped);

console.log(mapped instanceof MyArray); // false
console.log(mapped instanceof Array);   // true
